package com.wu.client.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wu.client.constant.RedisKeyConstant;
import com.wu.client.constant.RelationShipTypeEnum;
import com.wu.client.constant.ResTypeEnum;

import com.wu.client.dao.redis.Likes;
import com.wu.client.service.MvService;
import com.wu.client.service.RelationshipService;
import com.wu.client.service.UserLikesService;
import com.wu.client.utils.ListUtil;
import com.wu.client.utils.MinIoUtil;
import com.wu.client.utils.PageRespUtil;
import com.wu.client.vo.res.PageResp;
import com.wu.client.vo.res.mv.MvBaseResp;
import com.wu.client.vo.res.mv.MvResp;
import com.wu.constant.Enum.MinIoNameEnum;
import com.wu.mongo.MainComment;
import com.wu.mysql.entiy.ArtistDO;
import com.wu.mysql.entiy.MvDO;
import com.wu.mysql.entiy.RelationshipDO;
import com.wu.mysql.mapper.ArtistMapper;
import com.wu.mysql.mapper.MvMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class MvServiceImpl extends ServiceImpl<MvMapper, MvDO> implements MvService {
    private final RelationshipService relationshipService;
    private final ArtistMapper artistMapper;
    private final MvMapper mvMapper;
    private final UserLikesService userLikesService;
    private final MinIoUtil minIoUtil;
    private final MongoTemplate mongoTemplate;
    private final StringRedisTemplate stringRedisTemplate;
    @Override
    public PageResp<MvBaseResp> getArtistMv(Long artistId, Long userId, Integer page, Integer limit) {
        RelationShipTypeEnum artistMv = RelationShipTypeEnum.ARTIST_MV;
        Page<RelationshipDO> relationshipDOPage = relationshipService.getPageBySourceId(artistMv, artistId, page, limit);
        List<RelationshipDO> records = relationshipDOPage.getRecords();
        if (CollectionUtil.isEmpty(records)){
            return new PageResp<>();
        }
        List<Long> mvIds = records.stream().map(RelationshipDO::getTargetId).toList();
        List<MvDO> mvDOS = mvMapper.selectBatchIds(mvIds);
        List<MvBaseResp> mvBaseRespList = BeanUtil.copyToList(mvDOS, MvBaseResp.class);
        Map<Long, Likes> longLikesMap = userLikesService.checkUserIfLike(ResTypeEnum.MV, userId, mvIds);
        for (MvBaseResp item : mvBaseRespList) {
            Likes likes = longLikesMap.get(item.getId());
            if (ObjectUtil.isNotNull(likes)){
                item.setIsLiked(likes.getIsLiked());
                item.setLikesCount(likes.getCount());
            }
        }
        return PageRespUtil.buildPageResp(page,limit,relationshipDOPage.getTotal(),mvBaseRespList);
    }

   @Override
public PageResp<MvBaseResp> getMvs(Integer page, Integer limit, Long userId, Integer region, Integer language, Integer type, String sort) {
    // 1. 设置分页请求
    Page<MvDO> mvDOPage = new Page<>(page, limit);

    // 2. 创建查询条件
    LambdaQueryWrapper<MvDO> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(ObjectUtil.isNotNull(region), MvDO::getRegion, region)
                .eq(ObjectUtil.isNotNull(language), MvDO::getLanguage, language)
                .eq(ObjectUtil.isNotNull(type), MvDO::getType, type)
                .orderByDesc(MvDO::getReleaseDate);

    // 3. 执行查询
    mvMapper.selectPage(mvDOPage, queryWrapper);
    List<MvDO> records = mvDOPage.getRecords();

    // 4. 如果没有记录，返回空的 PageResp
    if (CollectionUtil.isEmpty(records)) {
        return new PageResp<>();
    }

    // 5. 转换 MvDO 到 MvBaseResp
    List<MvBaseResp> mvBaseRespList = BeanUtil.copyToList(records, MvBaseResp.class);

    // 6. 获取所有 MV 的 ID
    List<Long> mvIds = records.stream().map(MvDO::getId).collect(Collectors.toList());

    // 7. 获取 MV 和艺术家的关系
    RelationShipTypeEnum artistMv = RelationShipTypeEnum.ARTIST_MV;
    List<RelationshipDO> relationshipDOList = relationshipService.getInTargetId(artistMv, mvIds);
       Map<Long, String> mvArtistMap = new HashMap<>();
       if (CollectionUtil.isNotEmpty(relationshipDOList)){
        // 8. 构建 MV 和艺术家关系的映射
        Map<Long, List<RelationshipDO>> mvArtistRelationMap = relationshipDOList.stream()
                .collect(Collectors.groupingBy(RelationshipDO::getTargetId));

        // 9. 获取所有艺术家的 ID
        List<Long> artistIds = relationshipDOList.stream()
                .map(RelationshipDO::getSourceId).distinct()
                .collect(Collectors.toList());

        // 10. 获取艺术家信息
        List<ArtistDO> artistDOS = artistMapper.selectBatchIds(artistIds);
        Map<Long, ArtistDO> artistMap = artistDOS.stream()
                .collect(Collectors.toMap(ArtistDO::getId, a -> a));

        // 11. 构建 MV 和艺术家名称的映射
         mvArtistMap = mvArtistRelationMap.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> entry.getValue().stream()
                                .map(relationshipDO -> artistMap.get(relationshipDO.getSourceId()))
                                .map(ArtistDO::getName)
                                .collect(Collectors.joining("/"))
                ));
    }
       Map<Long, Likes> longLikesMap = userLikesService.checkUserIfLike(ResTypeEnum.MV, userId, mvIds);
    // 12. 设置艺术家名称到 MvBaseResp
    for (MvBaseResp item : mvBaseRespList) {
        Long id = item.getId();
        String artistName = mvArtistMap.getOrDefault(id, "未知名歌手");
        Likes likes = longLikesMap.get(id);
        if (ObjectUtil.isNotNull(likes)){
            item.setIsLiked(likes.getIsLiked());
            item.setLikesCount(likes.getCount());
        }
        item.setArtists(artistName);
    }
       // 13. 返回分页响应
    return PageRespUtil.buildPageResp(page, limit, mvDOPage.getTotal(), mvBaseRespList);
}

    @Override
    public PageResp<MvBaseResp> getUserFavoritesMvs(Long userId, Integer page, Integer limit) {
        String userLikesRedisKey = RedisKeyConstant.getUserLikesRedisKey(ResTypeEnum.MV.getCode(), userId);
        Set<String> mvIds = stringRedisTemplate.opsForSet().members(userLikesRedisKey);
        if (CollectionUtil.isNotEmpty(mvIds)){
            List<Long> ids = mvIds.stream().map(Long::parseLong).toList();
            long count  = ids.size();
            ids = ListUtil.subListInPage(ids, page, limit);
            List<MvDO> mvDOS = this.listByIds(ids);
            if (CollectionUtil.isNotEmpty(mvDOS)){
                List<MvBaseResp> mvBaseRespList = mvDOS.stream().map(mvDO -> {
                    MvBaseResp mvBaseResp = BeanUtil.toBean(mvDO, MvBaseResp.class);
                    String artisName = relationshipService.getArtisName(mvDO.getId(), RelationShipTypeEnum.ARTIST_MV);
                    mvBaseResp.setArtists(artisName);
                    String url = minIoUtil.getFileUrlDefault(MinIoNameEnum.MV.getBucketName(), mvDO.getFileName());
                    mvBaseResp.setUrl(url);
                    return mvBaseResp;
                }).toList();
                return PageRespUtil.buildPageResp(page,limit,count, mvBaseRespList);
            }

        }
        return new PageResp<>();
    }

    @Override
    public MvResp getMvDetail(Long id, Long userId) {
        MvDO mvDO = this.getById(id);
        if (ObjectUtil.isNotNull(mvDO)){
            MvResp mvResp = BeanUtil.toBean(mvDO, MvResp.class);
            if (ObjectUtil.isNotNull(userId)){
                Likes likes = userLikesService.checkUserIfLike(ResTypeEnum.MV, userId, List.of(id)).get(id);
                if (ObjectUtil.isNotNull(likes)){
                    mvResp.setIsLiked(likes.getIsLiked());
                    mvResp.setLikesCount(likes.getCount());
                }
            }
            Integer code = ResTypeEnum.MV.getCode();
            Query query =new Query();
            query.addCriteria(Criteria.where("contentType").is(code)
                    .and("contentId").is(id));
            long count = mongoTemplate.count(query, MainComment.class);
            mvResp.setCommentsCount(count);
            String url = minIoUtil.getFileUrlDefault(MinIoNameEnum.MV.getBucketName(), mvDO.getFileName());
            mvResp.setUrl(url);
            return mvResp;
        }
        return null;
    }
}
